package com.woniuxy;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.woniuxy.jwt.Audience;
import com.woniuxy.jwt.JwtUtil;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

@Slf4j
@Component
public class AuthFilter implements GlobalFilter, Ordered {

    @Autowired
    private AuthService authService;

    @Autowired
    private Audience audience;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("开启过滤器");
        String url = exchange.getRequest().getURI().getPath();
        String parms=exchange.getRequest().getURI().getQuery();
        String jwt = exchange.getRequest().getHeaders().getFirst("jwt");
        //判断如果是登录注册的请求就直接放行
        if (url.endsWith("login")||url.endsWith("regist")||url.endsWith("getcode")||url.contains("rider")){
            return chain.filter(exchange);
        }
        //判断jwt的类型，如果是1，2，3就给予放行，0代表后台管理员，1代表用户，2代表商家
        if (jwt!=null){
            log.info(jwt);
            try{
                int type = JwtUtil.getType(jwt,audience.getBase64Secret());
                if (type ==1&&url.contains("user")){
                    return chain.filter(exchange);
                }else if(type ==2&&url.contains("shop")){
                    return chain.filter(exchange);
                }
            }catch (ExpiredJwtException e){
                log.error("jwt过期");
                e.printStackTrace();
                return authErro(exchange.getResponse(),"jwt过期");

            }catch (Exception e){
                log.error("系统错误");
                e.printStackTrace();
                return authErro(exchange.getResponse(),"系统错误");
            }
        }
        if (jwt==null){
            jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhY2NvdW50IjoiYWRtaW4iLCJpZCI6MSwiaXNzIjoiMDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjYiLCJpYXQiOjE2MTY5ODQ0NDcsImF1ZCI6Indvbml1eHkiLCJleHAiOjE2MTY5ODYyNDcsIm5iZiI6MTYxNjk4NDQ0N30.JH03r369lrQ3jQ0NbMMpkB0szXZlgeyeh78NdX_LVuA";
        }
        ResponseResult<Void> result = authService.parseJwt(jwt,url,parms);
        if (result.getCode()==402){
            return authErro(exchange.getResponse(),result.getMsg());
        }else if(result.getCode()==403){
            log.info("403错误");
            return authErro(exchange.getResponse(),result.getMsg());
        }else {
            log.info("链接放行");
            return chain.filter(exchange);
        }
    }

    private Mono<Void> authErro(ServerHttpResponse resp, String mess) {
        resp.setStatusCode(HttpStatus.UNAUTHORIZED);
        resp.getHeaders().add("Content-Type", "application/json;charset=UTF-8");

        DataBuffer buffer = resp.bufferFactory().wrap(mess.getBytes(StandardCharsets.UTF_8));
        return resp.writeWith(Flux.just(buffer));
    }

    @Override
    public int getOrder() {
        return -100;
    }
}
